/********************************************************************************
 * Project Name		[JavaSE_Fundamentals]
 * File Name     	[DetectClassInformation.java]
 * Creation Date 	[2015-01-01]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ********************************************************************************/
package reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Scanner;

/**
 * 反射 - 检测一个类所具有的属性, 构造方法和方法, 并以列表显示
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 * 
 */
public class DetectClassInformation {

	/**
	 * 检测指定类型的属性(包括私有属性)
	 * 
	 * @param classType
	 *            指定的类的类型
	 */
	public static void detectFieldInfo(Class<?> classType) {
		Field[] fields = classType.getDeclaredFields();
		for (Field field : fields) {
			System.out.print("    ");
			// 获得修饰符
			String modifier = Modifier.toString(field.getModifiers());
			if (modifier.length() > 0) {
				System.out.print(modifier + " ");
			}
			// 获得属性类型
			String fieldType = field.getType().getSimpleName();
			// 获得属性名称
			String fieldName = field.getName();
			System.out.println(fieldType + " " + fieldName + ";");
		}
	}

	/**
	 * 检测指定类型的构造方法(包括私有)
	 * 
	 * @param classType
	 *            指定的类的类型
	 */
	public static void detectConstructorInfo(Class<?> classType) {
		Constructor<?>[] constructors = classType.getDeclaredConstructors();
		for (Constructor<?> constructor : constructors) {
			System.out.print("    ");

			// 获得修饰符
			String modifier = Modifier.toString(constructor.getModifiers());
			if (modifier.length() > 0) {
				System.out.print(modifier + " ");
			}
			System.out.print(classType.getSimpleName() + " (");

			// 获得参数类型
			Class<?>[] parameterTypes = constructor.getParameterTypes();
			if (parameterTypes.length > 0) {
				for (int i = 0; i < parameterTypes.length; i++) {
					String parameterName = parameterTypes[i].getSimpleName();
					String parameterValue = "param" + (i + 1);
					System.out.print(parameterName + " " + parameterValue);
					if (i != (parameterTypes.length - 1)) {
						System.out.print(", ");
					}
				}
			}
			System.out.print(")");

			// 获得抛出的异常
			Class<?>[] exceptionTypes = constructor.getExceptionTypes();
			if (exceptionTypes.length > 0) {
				System.out.print(" throws ");
				for (int i = 0; i < exceptionTypes.length; i++) {
					String exceptionName = exceptionTypes[i].getSimpleName();
					System.out.print(exceptionName);
					if (i != (exceptionTypes.length - 1)) {
						System.out.print(", ");
					}
				}
			}
			System.out.println();
		}
	}

	/**
	 * 检测指定类型的方法(包括私有方法)
	 * 
	 * @param classType
	 *            指定的类的类型
	 */
	public static void detectMethodInfo(Class<?> classType) {
		Method[] methods = classType.getDeclaredMethods();
		for (Method method : methods) {
			System.out.print("    ");

			// 获得方法修饰符
			String modifier = Modifier.toString(method.getModifiers());
			if (modifier.length() > 0) {
				System.out.print(modifier + " ");
			}
			// 获得方法返回值类型
			String returnTypeName = method.getReturnType().getSimpleName();
			System.out.print(returnTypeName + " ");

			// 获得方法名称
			String methodName = method.getName();
			System.out.print(methodName + "(");

			// 获得方法参数列表
			Class<?>[] parameterTypes = method.getParameterTypes();
			if (parameterTypes.length > 0) {
				for (int i = 0; i < parameterTypes.length; i++) {
					String parameterName = parameterTypes[i].getSimpleName();
					String parameterValue = "param" + (i + 1);
					System.out.print(parameterName + " " + parameterValue);
					if (i != (parameterTypes.length - 1)) {
						System.out.print(", ");
					}
				}
			}
			System.out.print(")");

			// 获得方法抛出的异常
			Class<?>[] exceptionTypes = method.getExceptionTypes();
			if (exceptionTypes.length > 0) {
				System.out.print(" throws ");
				for (int i = 0; i < exceptionTypes.length; i++) {
					String exceptionName = exceptionTypes[i].getSimpleName();
					System.out.print(exceptionName);
					if (i != (exceptionTypes.length - 1)) {
						System.out.print(", ");
					}
				}
			}
			System.out.println();
		}
	}

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入完整的类名, 如java.lang.String");

		String className = scanner.next();
		scanner.close();
		try {
			Class<?> classType = Class.forName(className);

			// 获得类的修饰符
			String classModifier = Modifier.toString(classType.getModifiers());
			if (classModifier.length() > 0) {
				System.out.print(classModifier + " ");
			}

			System.out.print("class " + classType.getSimpleName());

			// 是否有继承的类
			Class<?> superClassType = classType.getSuperclass();
			if (superClassType != null && superClassType != Object.class) {
				System.out.print(" extends " + superClassType.getSimpleName());
			}

			// 是否有实现的接口
			Class<?>[] interfaces = classType.getInterfaces();
			if (interfaces.length > 0) {
				System.out.print(" implements ");
				for (int i = 0; i < interfaces.length; i++) {
					System.out.print(interfaces[i].getSimpleName());
					if (i != (interfaces.length - 1)) {
						System.out.print(", ");
					}
				}
			}

			System.out.println(" {");

			detectFieldInfo(classType);
			System.out.println();
			detectConstructorInfo(classType);
			System.out.println();
			detectMethodInfo(classType);

			System.out.println("}");

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}
